package com.bs.demo.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bs.demo.common.R;
import com.bs.demo.entity.ThData;
import com.bs.demo.service.DataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.bs.demo.controller.NewDataController.NEWTHDATA;

@Slf4j
@RestController
@RequestMapping("/ThData")
public class ThDataController {

    @Autowired
    private DataService dataService;

    static Integer RECLOCK=0;

    /**
     * 灯的状态：
     * 0：关灯状态
     * 1：开灯状态
     */
    static Integer LIGHTSTATIC=0;


    /**
     * 0:关灯
     * 1：开灯
     * 2：智能
     */
    static Integer CONLIGHTROCK=2;
    /**
     * 0：需要开启灯光
     * 1：不需要开启灯光
     */
    static Integer NEEDLIGHT=0;

    /**
     * 光线阈值
     */
    static Integer RAY=40;

    /**
     * 删除七日前的数据
     * @return
     */
    @DeleteMapping("/delete7")
    public R<String> deleteAWeek(){
        LocalDate date=LocalDate.now().minusDays(7);
        List<ThData> list = dataService.list();
        List<ThData> listIds = list.stream().map((item) -> {
            ThData lsdata = new ThData();
            LocalDate dateNow = lsdata.getDate();
            if (dateNow.isBefore(date)) {
                return lsdata;
            }
            return null;
        }).collect(Collectors.toList());

        dataService.removeByIds(listIds);
        log.info("删除七天前数据成功");
        return R.success("成功删除");
    }


    @GetMapping("/list")
    public List<ThData> list(){
        LambdaQueryWrapper<ThData> queryWrapper=new LambdaQueryWrapper();
        queryWrapper.orderByDesc(ThData::getId).last("limit 10");

        List<ThData> list = dataService.list(queryWrapper);
//        LambdaQueryWrapper<ThData> last = queryWrapper.orderByDesc().last("limit 20");

        return list;
    }


    /**
     * 删除所有信息
     * @return
     */
    @DeleteMapping("/deleteAll")
    public R<String> DeleteAll(){

        dataService.remove(new QueryWrapper<>());
        return R.success("成功格式化");
    }

    /**
     * 查询接收数据的函数状态
     * @return
     */
    @GetMapping("/RELOCK")
    public Integer GetRLOCK(){
        return RECLOCK;
    }

    @PostMapping("/Threshold/{thre}")
    public int Threshold(@PathVariable int thre){
        RAY=thre;
        log.info("阈值控制"+String.valueOf(RAY));
        return RAY;
    }

    /**
     * 控制灯的开关
     * @param con
     */
    @PostMapping("/ContLight/{con}")
    public int  Cont(@PathVariable int con){
        CONLIGHTROCK=con;
        log.info("灯控制"+String.valueOf(CONLIGHTROCK));
        return CONLIGHTROCK;
    }

    /**
     * 返回灯的状态
     * @return
     */
    @GetMapping("/LightStatic")
    public int lightStatic(){
        return LIGHTSTATIC;
    }

    /**
     * 用于接收硬件传输来的信息并存入数据库和中控发送指令
     * @throws Exception
     */
    @Async
    @PostMapping  ("/Receive")
    public void Receive() throws Exception{
        log.info("开始接收数据");
        RECLOCK=1;
        DatagramSocket socket=new DatagramSocket(10000);
        byte[] butter=new byte[1024*64];
        DatagramPacket packet=new DatagramPacket(butter, butter.length);
        ThData thData =new ThData();
        int len;
        while (true){

            socket.receive(packet);
            len=packet.getLength();
            InetAddress address = packet.getAddress();
            int port = packet.getPort();
            String rs=new String(butter,0,len,"GBK");
            log.info("");
            log.info(rs+"接收到的数据");

            if (len>5){
                thData.setTemperature(getNum(rs.substring(0, 6)));
                thData.setHumidity(getNum(rs.substring(7,13)));
                thData.setRay(getNum(rs.substring(14,21)));
                thData.setSmoket(getNum(rs.substring(21,27)));
                thData.setInf(getNum(rs.substring(27)));
                dataService.saveThData(thData);


            if (thData.getInf()==1&&thData.getRay()<RAY){
                NEEDLIGHT=1;
                log.info(NEEDLIGHT+"需要灯状态");
            }else {
                NEEDLIGHT=0;
                log.info(NEEDLIGHT+"需要灯状态");
            }
            NEWTHDATA=thData;
            NEWTHDATA.setDate(LocalDate.now());
            NEWTHDATA.setTime(LocalTime.now());

            if (CONLIGHTROCK==0){
                log.info("0" + NEEDLIGHT+ address);
                DatagramPacket udpSend = udpSend("00",address,port);
                socket.send(udpSend);
                LIGHTSTATIC=0;
                log.info("发送00"+"到"+address+"端口"+port);

            } else if (CONLIGHTROCK==1){
                DatagramPacket udpSend = udpSend("01",address,port);
                socket.send(udpSend);
                LIGHTSTATIC=1;
                log.info("发送01到"+address+"端口"+port);
            }else {
                DatagramPacket udpSend = udpSend("0"+NEEDLIGHT,address,port);
                socket.send(udpSend);
                LIGHTSTATIC=NEEDLIGHT;
                log.info("发送"+"0"+NEEDLIGHT+"到"+address+"端口"+port);
            }
            }
        }
    }
    public int getNum(String str){
        String regEx="[^0-9]";
        Pattern p = Pattern.compile(regEx);
        Matcher Temp = p.matcher(str);
        String s = Temp.replaceAll("");
        return Integer.parseInt(s);
    }

    private DatagramPacket udpSend(String s, InetAddress address, int port) throws Exception{
//        byte[] butter = s.getBytes("GBK");
//        String gbk= URLEncoder.encode(s,"GBK");
//        log.info(gbk+"GBK字符");
        byte[] butter = s.getBytes();
//        log.info("butter");
//        log.info(butter.toString());
        DatagramPacket packet = new DatagramPacket(butter, butter.length,address,port);
        return packet;
    }


}
